package rest

import (
	"errors"
	"net/http"

	"ldaccount/pkg/is"

	"ldaccount/internal/service"

	"github.com/labstack/echo/v4"

	"ldaccount/pkg/lueerror"

	"ldaccount/internal/conf"
	"ldaccount/pkg/log"
)

type Base struct {
	logger log.Factory
	cfg    *conf.Config
}

var base *Base

func InitEchoBase(logger log.Factory, cfg *conf.Config) {
	base = &Base{
		logger: logger,
		cfg:    cfg,
	}
}

// ParseBody 请求 body 解析
func (b *Base) ParseBody(c echo.Context, model interface{}) lueerror.LueError {
	if err := c.Bind(model); err != nil {
		return lueerror.InvalidRequest(err)
	}
	if errV := c.Validate(model); errV != nil {
		return lueerror.InvalidRequest(errV)
	}
	return nil
}

type httpResp struct {
	Code    string      `json:"code"`
	Detail  string      `json:"detail"`
	Msg     string      `json:"msg"`
	Data    interface{} `json:"data"`
	Success bool        `json:"success"`
}

// SimpleRet simple http return
func (b *Base) SimpleRet(c echo.Context, ret interface{}, errL lueerror.LueError) error {
	if errL != nil {
		return errL
	}
	resp := &httpResp{
		Code:    "10000",
		Detail:  "",
		Msg:     "",
		Data:    ret,
		Success: true,
	}
	return c.JSON(http.StatusOK, resp)
}

// GenJwtToken 生成token
func (b *Base) GenJwtToken(gID, mobile, email, userName string) (string, lueerror.LueError) {
	return service.GetService().GenJwtToken(gID, mobile, email, userName)
}

func (b *Base) VerifyJwtToken(c echo.Context) (*service.JwtPayload, lueerror.LueError) {
	token := c.Request().Header.Get("G-Token")
	return service.GetService().VerifyToken(token)
}

func (b *Base) MobileCheck(mobile string) lueerror.LueError {
	if !is.CNMobile(mobile) {
		return lueerror.InvalidMobile(errors.New("手机号格式错误"))
	}
	return nil
}

func (b *Base) EmailCheck(email string) lueerror.LueError {
	if !is.Email(email) {
		return lueerror.InvalidEmail(errors.New("邮箱格式错误"))
	}
	return nil
}

func (b *Base) EmailMobileCheck(email, mobile string) lueerror.LueError {
	if email != "" {
		errL := b.EmailCheck(email)
		if errL != nil {
			return errL
		}
	}
	if mobile != "" {
		errL := b.MobileCheck(mobile)
		if errL != nil {
			return errL
		}
	}
	return nil
}

// ContainsStr 查询是否在数组中存在
func ContainsStr(a []string, x string) bool {
	for _, n := range a {
		if x == n {
			return true
		}
	}
	return false
}
